#ifndef DSPSIMULATOR_NOP_H
#define DSPSIMULATOR_NOP_H

#include <dspSimulator/targetMachine/dspInstruction.h>

class NOP : public DspInstruction {

public:

    NOP(u32 address = 0, u64 baseCycle = 0) :
            DspInstruction("NOP", address, baseCycle, 0) {}

    ~NOP() override = default;

    NOP(const NOP &nop) = default;

    /**
     * 构造一个指定数量的临时nop指令
     * @param numOfNop
     */
    static std::shared_ptr<NOP> getSpecialNOP(u32 numOfNop) {
        std::shared_ptr<NOP> nop = std::make_shared<NOP>();
        // 临时nop指令为Standard指令
        nop->isCompactInstruction = false;
        // 临时nop指令函数单元未知
        nop->funcUnit = FuncUnit::UNKNOWN_FUNC;
        // 临时nop指令相当于要求处理器执行numOfNop条nop指令
        nop->src1 = numOfNop;
        nop->numOfInsertNOP = nop->src1 - 1;
        // 临时nop指令的下一条指令不与当前临时nop指令并行
        nop->p = 0;
        return nop;
    }

    bool checkCondition(std::shared_ptr<DspMachine> dspMachine) override;

    /**
     * 将指令的ir执行函数加载到llvm jit执行引擎中
    */
    void loadInstIRIntoJit(llvm::LLVMContext *llvmContext, llvm::Module *module,
                           std::shared_ptr<llvm::IRBuilder<>> irBuilder) override;

    /**
     * 根据指令数据解码指令，并返回新的指令对象，该指令对象表示解码完成的指令
     * @param instInfo 指令数据
     * @param baseCycle 指令执行E1阶段的时钟周期
     * @return
     */
    std::shared_ptr<Instruction> decode(std::shared_ptr<InstInfo> instInfo, u64 baseCycle) override;

    /**
    * 自定义函数执行指令，不通过llvm jit执行指令
    * @param targetMachine 目标机对象
    * @param executePhase 当前指令的执行阶段（有些指令需要多个周期执行，每个周期的执行过程不一定相同，需要单独处理）
     */
    void executeCustom(std::shared_ptr<TargetMachine> targetMachine, ExecutePhase executePhase) override;

    /**
    * 生成标识指令信息的字符串
    * @return 标识指令信息的字符串
    */
    std::string toString() const override;

    std::shared_ptr<DspInstruction> clone() override;
};

#endif //DSPSIMULATOR_NOP_H
